/******************************************************************************* * MontiCore Language Workbench * Copyright (c) 2015, 2016, MontiCore, All rights reserved. * * This project is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this project. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ package de.monticore.genericgraphics.controller.util; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.SWTGraphics; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.GraphicalViewer; import org.eclipse.gef.LayerConstants; import org.eclipse.gef.editparts.LayerManager; import org.eclipse.gef.editparts.ScalableRootEditPart; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.ui.IEditorPart; import de.se_rwth.commons.logging.Log; /** * <p> * Utility class for saving images of {@link IEditorPart IEditorParts} with * {@link GraphicalViewer}. * </p> * The following formats are supported: * <ul> * <li>{@link SWT#IMAGE_BMP}</li> * <li>{@link SWT#IMAGE_ICO}</li> * <li>{@link SWT#IMAGE_JPEG}</li> * <li>{@link SWT#IMAGE_PNG}</li> * <li>{@link SWT#IMAGE_GIF}</li> * </ul> * * @author Tim Enger */ public class ImageSaveUtil { /** * <p> * Save editor content as image. * </p> * * @param editorPart The {@link IEditorPart} * @param viewer The {@link GraphicalViewer} that stores the figures * @param saveFilePath The file path * @param format The format of the image. Choose between: * <ul> * <li>{@link SWT#IMAGE_BMP}</li> * <li>{@link SWT#IMAGE_ICO}</li> * <li>{@link SWT#IMAGE_JPEG}</li> * <li>{@link SWT#IMAGE_PNG}</li> * <li>{@link SWT#IMAGE_GIF}</li> * </ul> * @return <tt>True</tt> if save was successful, otherwise <tt>false</tt>. */ public static boolean save(IEditorPart editorPart, GraphicalViewer viewer, String saveFilePath, int format) { if (editorPart == null || viewer == null || saveFilePath == null) { return false; } if (format != SWT.IMAGE_BMP && format != SWT.IMAGE_JPEG && format != SWT.IMAGE_ICO && format != SWT.IMAGE_PNG && format != SWT.IMAGE_GIF) { throw new IllegalArgumentException("Save format not supported"); } try { saveEditorContentsAsImage(editorPart, viewer, saveFilePath, format); } catch (Exception ex) { MessageDialog.openError(editorPart.getEditorSite().getShell(), "Save Error", "Could not save editor contents"); return false; } return true; } /** * <p> * Save editor content as image. * </p> * <p> * Ask the user for the file path and format. * </p> * * @param editorPart The {@link IEditorPart} * @param viewer The {@link GraphicalViewer} that stores the figures * @return <tt>True</tt> if save was successful, otherwise <tt>false</tt>. */ public static boolean save(IEditorPart editorPart, GraphicalViewer viewer) { if (editorPart == null || viewer == null) { return false; } String saveFilePath = getSaveFilePath(editorPart, viewer, -1); if (saveFilePath == null) { return false; } int format = SWT.IMAGE_JPEG; if (saveFilePath.endsWith(".jpeg")) { format = SWT.IMAGE_JPEG; } else if (saveFilePath.endsWith(".bmp")) { format = SWT.IMAGE_BMP; } else if (saveFilePath.endsWith(".ico")) { format = SWT.IMAGE_ICO; } else if (saveFilePath.endsWith(".png")) { format = SWT.IMAGE_PNG; } else if (saveFilePath.endsWith(".gif")) { format = SWT.IMAGE_GIF; } return save(editorPart, viewer, saveFilePath, format); } /** * <p> * Save editor content as image. * </p> * <p> * Query the {@link IEditorPart} for its {@link GraphicalViewer} via the * {@link IEditorPart#getAdapter(Class)} method. <br> * Ask the user for the file path and format. * </p> * * @param editorPart The {@link IEditorPart} * @return <tt>True</tt> if save was successful, otherwise <tt>false</tt>. */ public static boolean save(IEditorPart editorPart) { GraphicalViewer viewer = (GraphicalViewer) editorPart.getAdapter(GraphicalViewer.class); if (viewer != null) { return save(editorPart, viewer); } else { Log.error("0xA1111 Could not save as image! GraphicalViewer was not found!"); return false; } } /** * Ask user for file path. * * @param editorPart The {@link IEditorPart} * @param viewer The {@link GraphicalViewer} * @param format The format to use. Supported formats: * <ul> * <li>{@link SWT#IMAGE_BMP}</li> * <li>{@link SWT#IMAGE_ICO}</li> * <li>{@link SWT#IMAGE_JPEG}</li> * <li>{@link SWT#IMAGE_PNG}</li> * <li>{@link SWT#IMAGE_GIF}</li> * </ul> * @return The file path the user chose. */ private static String getSaveFilePath(IEditorPart editorPart, GraphicalViewer viewer, int format) { FileDialog fileDialog = new FileDialog(editorPart.getEditorSite().getShell(), SWT.SAVE); String[] filterExtensions = new String[] { "*.jpeg", "*.bmp", "*.ico", "*.png", "*.gif" }; if (format == SWT.IMAGE_BMP) { filterExtensions = new String[] { "*.bmp" }; } else if (format == SWT.IMAGE_JPEG) { filterExtensions = new String[] { "*.jpeg" }; } else if (format == SWT.IMAGE_ICO) { filterExtensions = new String[] { "*.ico" }; } else if (format == SWT.IMAGE_PNG) { filterExtensions = new String[] { "*.png" }; } else if (format == SWT.IMAGE_GIF) { filterExtensions = new String[] { "*.gif" }; } fileDialog.setFilterExtensions(filterExtensions); return fileDialog.open(); } private static void saveEditorContentsAsImage(IEditorPart editorPart, GraphicalViewer viewer, String saveFilePath, int format) { /* * 1. First get the figure whose visuals we want to save as image. So we * would like to save the rooteditpart which actually hosts all the * printable layers. NOTE: ScalableRootEditPart manages layers and is * registered graphicalviewer's editpartregistry with the key * LayerManager.ID ... well that is because ScalableRootEditPart manages all * layers that are hosted on a FigureCanvas. Many layers exist for doing * different things */ ScalableRootEditPart rootEditPart = (ScalableRootEditPart) viewer.getEditPartRegistry().get(LayerManager.ID); IFigure rootFigure = ((LayerManager) rootEditPart).getLayer(LayerConstants.PRINTABLE_LAYERS);// rootEditPart.getFigure(); Rectangle rootFigureBounds = rootFigure.getBounds(); /* * 2. Now we want to get the GC associated with the control on which all * figures are painted by SWTGraphics. For that first get the SWT Control * associated with the viewer on which the rooteditpart is set as contents */ Control figureCanvas = viewer.getControl(); GC figureCanvasGC = new GC(figureCanvas); /* * 3. Create a new Graphics for an Image onto which we want to paint * rootFigure */ Image img = new Image(null, rootFigureBounds.width, rootFigureBounds.height); GC imageGC = new GC(img); imageGC.setBackground(figureCanvasGC.getBackground()); imageGC.setForeground(figureCanvasGC.getForeground()); imageGC.setFont(figureCanvasGC.getFont()); imageGC.setLineStyle(figureCanvasGC.getLineStyle()); imageGC.setLineWidth(figureCanvasGC.getLineWidth()); // imageGC.setXORMode(figureCanvasGC.getXORMode()); Graphics imgGraphics = new SWTGraphics(imageGC); /* 4. Draw rootFigure onto image. After that image will be ready for save */ rootFigure.paint(imgGraphics); /* 5. Save image */ ImageData[] imgData = new ImageData[1]; imgData[0] = img.getImageData(); ImageLoader imgLoader = new ImageLoader(); imgLoader.data = imgData; imgLoader.save(saveFilePath, format); /* release OS resources */ figureCanvasGC.dispose(); imageGC.dispose(); img.dispose(); } }